package com.amphenol.oracle.verify.ui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterException;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;

import com.amphenol.oracle.util.ComponentUtil;
import com.amphenol.oracle.util.SwingUtils;
import com.amphenol.oracle.verify.BinFileApplication;
import com.amphenol.oracle.verify.VerifierApplication;

import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

import java.awt.Color;

public class MainFrame implements ActionListener {

	private final String ERROR="ERROR";
	private final String PASSED="PASSED";
	private final String FAILED="FAILED";
	
	JFrame jf;
	JPanel jpanel;
	JButton btnRun,btnPrint,btnPassed;
	JTextArea jta = null;
	JScrollPane jscrollPane;
	private JPanel panel;
	private JLabel partNumberLabel;
	private JTextField partNumber;
	private JComboBox<String> locationComboBox;
	private JLabel locationLabel;
	private JLabel serialNumberLabel;
	private JLabel baseSerialNumberLabel;
	private JTextField serialNumber;
	private JTextField baseSerialNumber;
	private VerifierApplication verifierApplication = new VerifierApplication();
	private BinFileApplication binFileApplication = new BinFileApplication();
	private JMenuBar menuBar;
	private JMenu mnFile;
	private JMenuItem mntmAbout;
	final String version = "3.01";

	public MainFrame() {

		
		jf = new JFrame("Oracle FRU Verify Plus"+version);
		Container contentPane = jf.getContentPane();
		contentPane.setLayout(new BorderLayout());

		jta = new JTextArea(10, 15);
		jta.setEditable(false);
		jta.setForeground(new Color(0, 0, 0));
		jta.setTabSize(4);
		jta.setFont(new Font("Arial", Font.PLAIN, 14));
		jta.setBackground(new Color(255, 255, 255));

		jscrollPane = new JScrollPane(jta);
		jpanel = new JPanel();
		jpanel.setLayout(new GridLayout(1, 3));

		contentPane.add(jscrollPane, BorderLayout.CENTER);
		contentPane.add(jpanel, BorderLayout.SOUTH);
		
		panel = new JPanel();
		panel.setBackground(new Color(211, 211, 211));
		jf.getContentPane().add(panel, BorderLayout.NORTH);
		
		locationLabel = new JLabel("Location");
		locationLabel.setHorizontalAlignment(SwingConstants.CENTER);
		locationLabel.setToolTipText("Location");
		
		locationComboBox = new JComboBox<String>();
		locationComboBox.setModel(new DefaultComboBoxModel<String>(new String[] {"China", "Mexico"}));
		locationComboBox.setToolTipText("");
		locationLabel.setLabelFor(locationComboBox);
		
		partNumberLabel = new JLabel("FRU Part Number :");
		partNumberLabel.setHorizontalAlignment(SwingConstants.CENTER);
		partNumberLabel.setToolTipText("");
		
		partNumber = new JTextField();
		partNumberLabel.setLabelFor(partNumber);
		partNumber.setColumns(10);
		
		serialNumberLabel = new JLabel("FRU Serial Number:");
		serialNumberLabel.setHorizontalAlignment(SwingConstants.CENTER);		
		serialNumber = new JTextField();
		serialNumberLabel.setLabelFor(serialNumber);
		serialNumber.setColumns(10);
		
		baseSerialNumberLabel = new JLabel("Base Part Serial Number :");
		
		baseSerialNumber = new JTextField();
		baseSerialNumberLabel.setLabelFor(baseSerialNumber);
		baseSerialNumber.setColumns(10);
		
		btnRun = new JButton("Run");
		btnRun.addActionListener(this);
		
		btnPrint = new JButton("Print");
		btnPrint.setEnabled(false);
		btnPrint.addActionListener(this);
		
		// 注册回车监听事件
		SwingUtils.enterPressesWhenFocused(btnRun);
		SwingUtils.enterPressesWhenFocused(btnPrint);
		ComponentUtil.setFocusComponents(new JComponent[]{partNumber,serialNumber,baseSerialNumber,btnRun,btnPrint});
		
		btnPassed = new JButton("");
		btnPassed.setEnabled(false);
		btnPassed.setBackground(new Color(211, 211, 211));
		btnPassed.setForeground(new Color(211, 211, 211));
		btnPassed.setFont(new Font("Arial", Font.BOLD, 17));
		
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
						.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING)
							.addGroup(gl_panel.createSequentialGroup()
								.addComponent(baseSerialNumberLabel)
								.addGap(21))
							.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
								.addComponent(locationLabel, GroupLayout.PREFERRED_SIZE, 124, GroupLayout.PREFERRED_SIZE)
								.addComponent(partNumberLabel, GroupLayout.PREFERRED_SIZE, 152, GroupLayout.PREFERRED_SIZE)))
						.addComponent(serialNumberLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
					.addGap(30)
					.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING)
						.addGroup(gl_panel.createSequentialGroup()
							.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
								.addComponent(baseSerialNumber, Alignment.LEADING)
								.addComponent(serialNumber, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE))
							.addGap(9))
						.addGroup(gl_panel.createSequentialGroup()
							.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
								.addComponent(locationComboBox, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
								.addComponent(partNumber, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE))
							.addGap(8)))
					.addGap(27)
					.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
						.addGroup(gl_panel.createSequentialGroup()
							.addComponent(btnRun)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(btnPrint))
						.addComponent(btnPassed, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
					.addContainerGap())
		);
		gl_panel.setVerticalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_panel.createSequentialGroup()
							.addContainerGap()
							.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
								.addComponent(locationLabel, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE)
								.addComponent(locationComboBox, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(ComponentPlacement.RELATED)
							.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
								.addComponent(partNumberLabel, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
								.addComponent(partNumber, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
							.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
								.addComponent(serialNumber, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addComponent(serialNumberLabel, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)))
						.addGroup(gl_panel.createSequentialGroup()
							.addGap(28)
							.addComponent(btnPassed, GroupLayout.PREFERRED_SIZE, 57, GroupLayout.PREFERRED_SIZE)))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
						.addComponent(baseSerialNumber, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(btnRun, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
						.addComponent(baseSerialNumberLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
						.addComponent(btnPrint))
					.addContainerGap())
		);
		panel.setLayout(gl_panel);

		jf.setSize(600, 700);
		jf.setLocation(400, 20);
		
		menuBar = new JMenuBar();
		jf.setJMenuBar(menuBar);
		
		mnFile = new JMenu("File");
		menuBar.add(mnFile);
		
		mntmAbout = new JMenuItem("About");
		mntmAbout.addActionListener(this);
		mnFile.add(mntmAbout);
		jf.setVisible(true);
		partNumber.requestFocus();
		jf.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
	}

	private void setVerifyResult(boolean bool,String message) {
		if(bool){
			btnPassed.setText(message);
			btnPassed.setEnabled(true);
			btnPassed.setBackground(new Color(0, 255, 0));
			btnPassed.setForeground(new Color(0, 0, 0));
			//panel.setBackground(new Color(100, 149, 237));
		}else {
			btnPassed.setText(message);
			btnPassed.setEnabled(true);
			btnPassed.setBackground(new Color(255, 0, 0));
			btnPassed.setForeground(new Color(0, 0, 0));
			//panel.setBackground(new Color(255, 0, 0));
		}
		
	}
	
	//empty input sources
	private void emptyInput(){
		
				serialNumber.setText("");
				baseSerialNumber.setText("");
				partNumber.setText("");
	}
	
	@Override
	/**
	 * 覆盖actionPerformed 方法，添加检测业务
	 */
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getSource() == btnRun){
			//JOptionPane.showMessageDialog(btnRun, locationComboBox.getSelectedItem(), "Error", JOptionPane.ERROR_MESSAGE);
			try {
				jta.setText("");
				btnPrint.setEnabled(false);
				Map<String, String> iniFieldsMap = binFileApplication.getIniFields();
				//判断 part number 是为空
				if(partNumber.getText().trim()==null
					|| "".equals(partNumber.getText().trim())  ){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog("FRU_Part_Number input Empty");
					JOptionPane.showMessageDialog(jf, "FRU_Part_Number Can not Empty", "Warning", JOptionPane.WARNING_MESSAGE);
					jta.append("ERROR : FRU_Part_Number input Empty");
					return;
				}
				//判断 part number 是否在配置文件中
				if(!iniFieldsMap.get("FRU_Part_Number").equals(partNumber.getText().trim())){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog("FRU_Part_Number not found");
					JOptionPane.showMessageDialog(jf, "FRU_Part_Number not found,please check!", "Error", JOptionPane.ERROR_MESSAGE);
					partNumber.setText("");
					jta.append("ERROR : FRU_Part_Number not found");
					return;
				}
				//判断 serialNumber 和  baseserialNumber  
				if(serialNumber.getText().trim()==null || "".equals(serialNumber.getText().trim()) 
						|| baseSerialNumber.getText().trim() == null || "".equals(baseSerialNumber.getText().trim())){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog("FRU_Serial_Number or Base_Serial_Number input Empty");
					JOptionPane.showMessageDialog(jf, "FRU_Serial_Number or Base_Serial_Number Can not empty! ", "Warning", JOptionPane.WARNING_MESSAGE);
					jta.append("ERROR : FRU_Serial_Number or Base_Serial_Number input Empty");
					return;
				}
				/* 执行判断serial Number 和 base serial number 正确性。
				 * 如果location 是 China serial Number 465787C
				 * 如果location 是Mexico serial Number 465787M
				 */
				String sn = serialNumber.getText().trim();
				String regex=binFileApplication.getSerialNumberRegex(partNumber.getText().trim(),(String)locationComboBox.getSelectedItem());
				
				Pattern pattern = Pattern.compile(regex);
				Matcher matcher = pattern.matcher(sn);
				
				if(!matcher.matches()){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog("FRU_Serial_Number input error,the number not match "+regex);
					JOptionPane.showMessageDialog(jf, "FRU_Serial_Number Input Error", "Error", JOptionPane.ERROR_MESSAGE);
					//empty Input
					serialNumber.setText("");
					jta.append("ERROR : FRU_Serial_Number input error,the number not match "+regex);
					return;
				}
				
				String baseSN = baseSerialNumber.getText().trim();
				regex = binFileApplication.getBaseSerialNumberRegex((String)locationComboBox.getSelectedItem());
				pattern = Pattern.compile(regex);
				matcher = pattern.matcher(baseSN);
				
				if(!matcher.matches()){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog("Base_Part_Serial_Number input error,the number not match "+regex);
					JOptionPane.showMessageDialog(jf, "Base_Part_Serial_Number Input Error", "Error", JOptionPane.ERROR_MESSAGE);
					//empty Input
					baseSerialNumber.setText("");
					jta.append("ERROR : Base_Part_Serial_Number input error,the number not match "+regex);
					return;
				}
				String binfile=binFileApplication.getBinFileName(sn);
				String htmlfile=binFileApplication.getHtmlFileName(iniFieldsMap.get("SpecPartNo"));
				if("".equals(binfile)){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog(sn+"_*.bin File not found ");
					JOptionPane.showMessageDialog(jf, "bin File not found ", "Error", JOptionPane.ERROR_MESSAGE);
					//empty Input
					emptyInput();
					jta.append("ERROR : "+sn+"_*.bin File not found ");
					return;
				}
				if("".equals(htmlfile)){
					setVerifyResult(false,ERROR);
					verifierApplication.writeErrorLog(htmlfile+".html File not found ");
					JOptionPane.showMessageDialog(jf, iniFieldsMap.get("SpecPartNo")+".HTML File not found ", "Error", JOptionPane.ERROR_MESSAGE);
					//empty Input
					emptyInput();
					jta.append("ERROR : "+htmlfile+".html File not found ");
					return;
				}
				Process process = verifierApplication.runFruidVerifier(binfile,htmlfile);
				List<String> output=verifierApplication.getProcessOutput(process);
				
				for (String line : output) {
					jta.append(line+System.getProperty("line.separator"));
				}
				
				List<String> errormessage=verifierApplication.getErrorMessage(output);
				if(errormessage.size()>0){
					
					jta.append("====================================="+System.getProperty("line.separator"));
					jta.append("["+new Date().toString()+"] ");
					jta.append(" Amphenol GIS("+(String)locationComboBox.getSelectedItem()+") Verify Result [ Failed ]" +System.getProperty("line.separator"));
					verifierApplication.writerVerifierLog(sn, jta.getText(), iniFieldsMap.get("FRU_Part_Number"));
					btnPrint.setEnabled(true);
					setVerifyResult(false,FAILED);
					JOptionPane.showMessageDialog(jf,"Find Many Errors  !", "FAILED", JOptionPane.ERROR_MESSAGE);
					//empty Input
					emptyInput();
					return;
				}
				
				List<String> verifyResult=verifierApplication.verify(output, iniFieldsMap, sn, baseSN);
				if(verifyResult.size()==0){
					jta.append("====================================="+System.getProperty("line.separator"));
					jta.append("["+new Date().toString()+"] ");
					jta.append(" Amphenol GIS("+(String)locationComboBox.getSelectedItem()+") Verify Result [ Passed ]" +System.getProperty("line.separator"));
					verifierApplication.writerVerifierLog(sn, jta.getText(), iniFieldsMap.get("FRU_Part_Number"));
					btnPrint.setEnabled(true);
					setVerifyResult(true,PASSED);
					//empty Input
					emptyInput();
					return;
				}else {
					jta.append("====================================="+System.getProperty("line.separator"));
					jta.append("["+new Date().toString()+"] ");
					jta.append(" Amphenol GIS("+(String)locationComboBox.getSelectedItem()+") Verify Result [ Failed ]" +System.getProperty("line.separator"));
					jta.append("====================================="+System.getProperty("line.separator"));
					StringBuilder sb= new StringBuilder();
					for (String string : verifyResult) {
						jta.append(string);
						sb.append(string);
					}
					verifierApplication.writerVerifierLog(sn, jta.getText(), iniFieldsMap.get("FRU_Part_Number"));
					btnPrint.setEnabled(true);
					setVerifyResult(false,FAILED);
					JOptionPane.showMessageDialog(jf,sb.toString(), "FAILED", JOptionPane.ERROR_MESSAGE);
					//empty Input
					emptyInput();
					return;
				}
				
			} catch (IOException e2) {
				// TODO Auto-generated catch block
				setVerifyResult(false,ERROR);
				verifierApplication.writeErrorLog(e2.getLocalizedMessage());
				JOptionPane.showMessageDialog(jf,e2.getLocalizedMessage(), "Error", JOptionPane.ERROR_MESSAGE);
				//empty Input
				emptyInput();
				jta.append(e2.getLocalizedMessage());
				e2.printStackTrace();
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				setVerifyResult(false,ERROR);
				verifierApplication.writeErrorLog(e1.getLocalizedMessage());
				JOptionPane.showMessageDialog(jf,e1.getLocalizedMessage(), "Error", JOptionPane.ERROR_MESSAGE);
				//empty Input
				emptyInput();
				jta.append(e1.getLocalizedMessage());
				e1.printStackTrace();
			} 
			
		}
		
		if(e.getSource()==btnPrint){
			try {
				jta.print();
				btnPrint.setEnabled(false);
			} catch (PrinterException e1) {
				// TODO Auto-generated catch block
				setVerifyResult(false,ERROR);
				verifierApplication.writeErrorLog(e1.getLocalizedMessage());
				JOptionPane.showMessageDialog(jf,e1.getLocalizedMessage(), "Error", JOptionPane.ERROR_MESSAGE);
				jta.append("[ Print Error ]"+e1.getLocalizedMessage());
				e1.printStackTrace();
			}
		}
		if(e.getSource()==mntmAbout){
			JOptionPane.showMessageDialog(jf, "Verison "+version+System.getProperty("line.separator")+"Amphenol GIS(Changzhou) Rocky cai");
		}
	}
	
	public static void main(String[] args) {
		new MainFrame();
	}
}

